#ifndef WORKFLOW_H
#define WORKFLOW_H

#include "Camera/camera.h"
#include "RobotArm/robotarm.h"
#include "ImageProcessor/imageprocessor.h"
#include "ClientStation/clientstation.h"
#include "ModbusTcp/ndc_client.h"
#include "RobotArm/robotarmmonitor.h"
#include "Calibration/calibration.h"
#include "Light/light.h"


enum class Event_State{
    Event_OK = 0,
    Error_Robot_Motion = 1, //机械臂运动错误
    Error_Robot_Initialization = 2, //机械臂初始化错误

    Error_Vision_Location = 3, //视觉定位错误
    Error_Camera_Initialization = 4, //相机初始化错误

    Error_Modbus_Initialization = 5, //Modbus初始化错误
    Error_Modbus_Connection = 6,
    

    Error_Suction = 7, //吸料异常
    Error_Blowing = 8, //吹料异常
    Error_Washing = 9, //洗料异常
};



enum FlowStep {

    STEP_Check_RobotArm_State = 10,    //检测机械臂状态
    STEP_Check_Camera_State = 11,      //检测相机状态
    STEP_Check_Modbus_State = 12,      //检测和NDC通讯的modbus的状态
    STEP_Check_Light_State = 13,       //检测光源状态

    STEP_WaitFor_StationRequest = 21,      //AGV到位机台号
    STEP_WaitFor_Take_FinishedWorkPiece_to_AGV = 22,  //等待取加工完成料到AGV
    STEP_WaitFor_Take_RawWorkPiece_To_CNC_Station = 23, //等待把生料从二次定位平台放到CNC机台


    STEP_Take_RawWorkPiece_To_SecondLocationHolder = 30,  //把生料放到二次定位平台
    //移动到取生料点,
    //  吸料  ,异常返回状态，回到待机点
    //移动到二次定位平台，
    //  吹料
    //回到待机点
    STEP_Using_Vision_To_Correct_AGV_Pose = 40, //使用视觉进行位置校准
    //移动到视觉定位点
    //视觉定位
    //回到待机点

    STEP_Take_FinishedWorkPiece_To_OK_Zone = 50, //把加工完成料放到OK区
    //移动到CNC机台
    //   吸料 异常返回状态，回到待机点
    //移动到洗料池
    //   洗料 异常返回状态，停止？ 回到待机点
    //移动到合格区
    //   吹料 异常，停止
    //回到待机点
    //需要记录放了哪2个位置
    STEP_Take_FinishedWorkPiece_To_NG_Zone = 60, //把加工完成料放到NG区

    //移动机械臂到CNC机台
    //   吸料 ，异常返回状态，回到待机点
    //移动机械臂到非合格区
    //   吹料， 异常返回状态，停止
    //回到待机点
    STEP_Take_RawWorkPiece_To_CNC_Station = 70, //把生料从二次平台放到CNC机台
    //移动到二次定位平台
    //  吸料 ， 异常返回状态，回到待机点
    //移动到CNC机台
    //  吹料， 异常返回状态，停止
    //回到待机点

    STEP_Send_State_To_NDC = 80, //发送状态给NDC

    //异常：吸真空异常，回到待机点，是否需要人工操作
    //       视觉定位异常，回到待机点，是否需要人工操作


    //
    //1 取生料放到定位盘 (OK)，吸真空异常，警告需要人工处理
    //2 去拍照位进行视觉定位 (OK)，视觉定位异常，警告需要人工处理
    //3 取加工完成物料放到正常产品区 (OK) 或异常产品区（NG），吸真空异常，警告需要人工处理。
    //3 抓取未加工料到CNC机台，吸真空异常，警告需要人工处理
    //4 发送完成信号

    /*
    需要实现的业务逻辑：
    1.正常的上下料流程
    2.取料异常（真空吸无物料），机械臂直接退出机台到待命点，然后给AGV发送取消此任务，前往下一机台继续取料
    3.如果拍机台二维码异常（比如停车位置偏差过大，拍不到二维码），机械臂缩回到待命位，给机械臂发送取消任务，前往下一个机台继续取料
    4.NG料的处理：机台判断为NG料，会给AGVNG料信号，此物料取出后放在空框中后将框放到AGV上面的两个NG位置上；AGV空闲是将NG料带框放到CNC机台旁的NG货架上
    5.收到AGV的暂停信号，能暂停机械臂的移动，等待没有暂停信号后，继续运行
    */

    STEP_Abortion = 90,

    STEP_Manual_Handling = 100,

    STEP_IDLE = 0,
};


class WorkFlow : public QObject
{

   Q_OBJECT

public:
    explicit WorkFlow(QObject *parent = 0);
    ~WorkFlow();

    WorkFlow(QObject *parent,
             Camera* camera,
             RobotArm* robot_arm,
             ImageProcessor* image_processor,
             NDC_Client* NDC_Client);

    void set_main_thread(QObject *thread);

    //
    void setWorkFlag(bool state){ work_flag = state; }
    //

    //检测机械臂状态，是否可用
    void check_RobotArm_State();
    //检测相机状态，是否可用
    void check_Camera_State();
    //检测Modbus状态，是否可用
    void check_Modbus_State();
    //等待AGV到位信号
    void waitFor_StationRequest();
    //取生料到二次定位平台
    void take_RawWorkPiece_To_SecondLocationHolder();
    //使用视觉进行位置纠正
    void by_Vision_To_correct_AGV_pose();
    //取加工完成物料，放置在合格区
    void take_FinishedWorkPiece_To_OK_Zone();
    //取加工完成物料，放置在非合格区
    void take_FinishedWorkPiece_To_NG_Zone();
    //从二次定位平台取料
    void take_RawWorkPiece_To_CNC_Station();
    //向DNC发送任务状态
    void send_State_To_NDC();
    //关闭流程
    void close_Flow();

    void stop_work_flow();

signals:
    void sig_finish();

    void newData(QByteArray data);

public slots:
    //
    void run_work_flow();

private:

    QThread * main_thread_;

    bool work_flag = false;
    //相机类
    Camera* camera_;
    //机械臂类
    RobotArm* robot_arm_; //workthread_robot_arm_
    //相机处理类
    ImageProcessor* image_processor_;
    //跟NDC通讯类
    NDC_Client* NDC_Client_;
    //矫正位姿类
    Calibration* calibration_;
    //光源控制类
    Light light_;

    FlowStep current_flow_step;
    Event_State current_event_state_;



};

#endif // WORKFLOW_H
